package cn.sciento.wechat.enterprise.service.impl;

import cn.sciento.starter.integrate.dto.SyncCorpResultDTO;
import cn.sciento.starter.integrate.dto.SyncDeptDTO;
import cn.sciento.starter.integrate.dto.SyncUserDTO;
import cn.sciento.starter.integrate.entity.CorpHrSync;
import cn.sciento.starter.integrate.service.AbstractCorpSyncService;
import cn.sciento.wechat.enterprise.constant.WechatConstans;
import cn.sciento.wechat.enterprise.constant.WechatErrorCode;
import cn.sciento.wechat.enterprise.dto.*;
import cn.sciento.wechat.enterprise.enums.SecretTypeEnum;
import cn.sciento.wechat.enterprise.service.WechatCorpAddressService;
import cn.sciento.wechat.enterprise.service.WechatTokenService;
import cn.sciento.wechat.enterprise.utils.LogUtils;
import com.alibaba.fastjson.JSON;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

public class WechatCorpSyncServiceImpl implements AbstractCorpSyncService {
  private static final Logger logger = LoggerFactory.getLogger(WechatCorpSyncServiceImpl.class);

  @Autowired
  private WechatCorpAddressService wechatCorpAddressService;

  @Autowired
  private WechatTokenService wechatTokenService;

  public String corpSyncType() {
    return "WX";
  }

  public String getAccessToken(CorpHrSync corpHrSync) {
    TokenDTO tokenDTO;
    TokenDTO result;
    switch (corpHrSync.getAuthType()) {
      case "SELF":
        tokenDTO = this.wechatTokenService.getTokenWithCache(corpHrSync.getAppId(), corpHrSync.getAppSecret(), SecretTypeEnum.CORP);
        if (StringUtils.hasText(tokenDTO.getAccess_token()))
          return tokenDTO.getAccess_token();
        return null;
      case "THIRD":
        result = this.wechatTokenService.getTokenFromThirdPart(corpHrSync.getAuthAddress());
        if (result != null && StringUtils.hasText(result.getAccess_token()))
          return result.getAccess_token();
        return null;
    }
    return null;
  }

  public SyncCorpResultDTO syncCorp(List<SyncDeptDTO> syncDeptList, List<SyncUserDTO> syncUserList, String fileName, Boolean useGeneratedDeptId, String accessToken) {
    SyncCorpResultDTO syncCorpResultDTO = (new SyncCorpResultDTO()).setDeptStatus(Boolean.valueOf(true)).setEmployeeStatus(Boolean.valueOf(true));
    Map<Long, Long> successDeptIdMap = new HashMap<>(16);
    List<String> successUserIds = new ArrayList<>();
    File file = new File(FileUtils.getTempDirectoryPath() + File.separator + "syncCorp" + File.separator + fileName);
    try {
      List<String> deleteUserIds = new ArrayList<>();
      List<WechatSyncUserDTO> insertUsers = new ArrayList<>();
      Map<String, WechatSyncUserDTO> updateUsersMap = new HashMap<>(16);
      List<Long> deleteDeptIds = new ArrayList<>();
      List<WechatSyncDeptDTO> insertDeptList = new ArrayList<>();
      List<WechatSyncDeptDTO> updateDeptList = new ArrayList<>();
      List<WechatSyncUserDTO> weChatSyncUserList = new ArrayList<>();
      List<WechatSyncDeptDTO> weChatSyncDeptList = new ArrayList<>();
      convertSyncUserDTOS(syncUserList, weChatSyncUserList);
      convertSyncDeptDTOS(syncDeptList, weChatSyncDeptList);
      weChatSyncUserList.forEach(item -> {
        switch (item.getSyncType()) {
          case "create":
            insertUsers.add(item);
            return;
          case "update":
            updateUsersMap.put(item.getUserid(), item);
            return;
          case "delete":
            deleteUserIds.add(item.getUserid());
            return;
        }
        LogUtils.info(logger, file, "Employees synchronization object has no synchronization type: " + item.toString());
      });
      weChatSyncDeptList.forEach(item -> {
        switch (item.getSyncType()) {
          case "create":
            insertDeptList.add(item);
            return;
          case "update":
            updateDeptList.add(item);
            return;
          case "delete":
            deleteDeptIds.add(item.getId());
            return;
        }
        LogUtils.info(logger, file, "Departments synchronization object has no synchronization type: " + item.toString());
      });
      ResultCount resultCount = new ResultCount();
      LogUtils.info(logger, file, "***Start syncing Enterprise WeChat departments***");
      insertDept(file, insertDeptList, useGeneratedDeptId, accessToken, successDeptIdMap, resultCount);
      deleteDept(file, deleteDeptIds, deleteUserIds, updateUsersMap, successDeptIdMap, successUserIds, accessToken, resultCount);
      updateDeptList(file, updateDeptList, successDeptIdMap, accessToken, resultCount);
      LogUtils.info(logger, file, "**Start syncing Enterprise WeChat employees**");
      deleteUsers(file, deleteUserIds, successUserIds, accessToken, resultCount);
      insertUsers(file, insertUsers, successDeptIdMap, successUserIds, accessToken, resultCount);
      updateUsers(file, updateUsersMap, successDeptIdMap, successUserIds, accessToken, resultCount);
      if (resultCount.getDeptFailCount() > 0)
        syncCorpResultDTO.setDeptStatus(Boolean.valueOf(false));
      if (resultCount.getUserFailCount() > 0)
        syncCorpResultDTO.setEmployeeStatus(Boolean.valueOf(false));
      LogUtils.info(logger, file, "Sync is complete. Departments Synced successfully count: " + resultCount

              .getDeptSuccessCount() + "，synced failed count: " + resultCount
              .getDeptFailCount() + ".Employees synced successfully count: " + resultCount
              .getUserSuccessCount() + ",synced failed count: " + resultCount
              .getUserFailCount() + ".");
      return getSyncCorpResultDTO(syncCorpResultDTO, file).setDeptIdMap(successDeptIdMap)
              .setUserIds(successUserIds);
    } catch (Exception e) {
      LogUtils.error(logger, file, e.toString());
      return getSyncCorpResultDTO(syncCorpResultDTO.setEmployeeStatus(Boolean.valueOf(false)).setDeptStatus(Boolean.valueOf(false)), file)
              .setDeptIdMap(successDeptIdMap).setUserIds(successUserIds);
    }
  }

  private void convertSyncUserDTOS(List<SyncUserDTO> syncUserList, List<WechatSyncUserDTO> weChatSyncUserList) {
    syncUserList.forEach(e -> {
      WechatSyncUserDTO weChatSyncUserDTO = new WechatSyncUserDTO();
      BeanUtils.copyProperties(e, weChatSyncUserDTO);
      weChatSyncUserList.add(weChatSyncUserDTO);
    });
  }

  private void convertSyncDeptDTOS(List<SyncDeptDTO> syncDeptList, List<WechatSyncDeptDTO> weChatSyncDeptList) {
    syncDeptList.forEach(e -> {
      WechatSyncDeptDTO weChatSyncDeptDTO = new WechatSyncDeptDTO();
      BeanUtils.copyProperties(e, weChatSyncDeptDTO);
      weChatSyncDeptList.add(weChatSyncDeptDTO);
    });
  }

  private void insertDept(File file, List<WechatSyncDeptDTO> insertDeptList, Boolean useGeneratedDeptId, String accessToken, Map<Long, Long> successDeptIdMap, ResultCount resultCount) {
    if (!CollectionUtils.isEmpty(insertDeptList)) {
      ArrayList<WechatSyncDeptDTO> syncDeptDTOList = sortDept(insertDeptList);
      for (WechatSyncDeptDTO insertDept : syncDeptDTOList) {
        Long deptId = insertDept.getId();
        if (useGeneratedDeptId.booleanValue())
          insertDept.setId(null);
        boolean isParentIdMap = convertDeptParentId(insertDept, successDeptIdMap);
        LogUtils.info(logger, file, "Create Enterprise WeChat department:" + insertDept.toString());
        if (!isParentIdMap) {
          LogUtils.error(logger, file, "Create failed,the parent department does not exist.");
          resultCount.deptFail();
          continue;
        }
        if (!useGeneratedDeptId.booleanValue() && !checkDeptId(insertDept.getId())) {
          LogUtils.error(logger, file, "Create department failed, department id is greater than 32-bit integer value");
          resultCount.deptFail();
          continue;
        }
        CreateDeptResultDTO dept = this.wechatCorpAddressService.createDept(insertDept, accessToken);
        if (WechatErrorCode.SUCCESS.equals(dept.getErrcode())) {
          successDeptIdMap.put(deptId, Long.valueOf(dept.getId()));
          resultCount.deptSuccess();
          continue;
        }
        if (WechatErrorCode.DEPT_EXISTS.equals(dept.getErrcode()) &&
                !useGeneratedDeptId.booleanValue()) {
          LogUtils.info(logger, file, "Department already exists, update department");
          DefaultResultDTO defaultResultDTO = this.wechatCorpAddressService.updateDept(insertDept, accessToken);
          if (WechatErrorCode.SUCCESS.equals(defaultResultDTO.getErrcode())) {
            successDeptIdMap.put(deptId, deptId);
            resultCount.deptSuccess();
            continue;
          }
          resultCount.deptFail();
          LogUtils.error(logger, file, "Update failed：" + defaultResultDTO.getErrmsg());
          continue;
        }
        resultCount.deptFail();
        LogUtils.error(logger, file, "Create failed：" + dept.getErrmsg());
      }
    }
  }

  private void deleteDept(File file, List<Long> deleteDeptIds, List<String> deleteUserIds, Map<String, WechatSyncUserDTO> updateUsersMap, Map<Long, Long> successDeptIdMap, List<String> successUserIds, String accessToken, ResultCount resultCount) {
    while (!CollectionUtils.isEmpty(deleteDeptIds)) {
      Long deleteDeptId = deleteDeptIds.get(0);
      LogUtils.info(logger, file, "Change users in the department and its sub-departments before deleting the Enterprise WeChat department,id：" + deleteDeptId);
      DeptUserDTO usersByDeptId = this.wechatCorpAddressService.getUsersByDeptId(deleteDeptId, accessToken, 1);
      List<DeptUserDTO.UserlistBean> userList = usersByDeptId.getUserlist();
      if (!CollectionUtils.isEmpty(userList)) {
        List<String> userIds = (List<String>)userList.stream().map(DeptUserDTO.UserlistBean::getUserid).collect(Collectors.toList());
        for (String userId : userIds) {
          if (deleteUserIds.contains(userId)) {
            deleteUserIds.remove(userId);
            LogUtils.info(logger, file, "Delete Enterprise WeChat employees under the department,userid: " + userId);
            DefaultResultDTO defaultResultDTO1 = this.wechatCorpAddressService.deleteUserById(userId, accessToken);
            if (!WechatErrorCode.SUCCESS.equals(defaultResultDTO1.getErrcode())) {
              LogUtils.error(logger, file, "Delete failed: " + defaultResultDTO1.getErrmsg());
              resultCount.userFail(1);
              continue;
            }
            successUserIds.add(userId);
            resultCount.userSuccess(1);
            continue;
          }
          if (updateUsersMap.containsKey(userId)) {
            WechatSyncUserDTO syncUserDTO = updateUsersMap.get(userId);
            updateUsersMap.remove(userId);
            boolean isAllDepartIdsMap = convertUserDepart(syncUserDTO, successDeptIdMap);
            LogUtils.info(logger, file, "Update Enterprise WeChat employees under the department:" + syncUserDTO.toString());
            if (!isAllDepartIdsMap) {
              LogUtils.error(logger, file, "Update employee failed, department does not exist.");
              resultCount.userFail(1);
              continue;
            }
            DefaultResultDTO defaultResultDTO1 = this.wechatCorpAddressService.updateUser(syncUserDTO, accessToken);
            if (!WechatErrorCode.SUCCESS.equals(defaultResultDTO1.getErrcode())) {
              LogUtils.error(logger, file, "Update failed: " + defaultResultDTO1.getErrmsg());
              resultCount.userFail(1);
              continue;
            }
            successUserIds.add(userId);
            resultCount.userSuccess(1);
            continue;
          }
          GetUserDTO userById = this.wechatCorpAddressService.getUserById(userId, accessToken);
          LogUtils.error(logger, file, "The employee is not included in the sync employees: " + userById.toString());
        }
      }
      DeptListDTO deptList = this.wechatCorpAddressService.getDeptList(deleteDeptId, accessToken);
      if (!CollectionUtils.isEmpty(deptList.getDepartment())) {
        LogUtils.info(logger, file, "Delete Enterprise WeChat department id: " + deleteDeptId + ",delete sub-department first");
        deleteDeptIds.removeAll((Collection)deptList
                .getDepartment().stream().map(DeptListDTO.DepartmentBean::getId).collect(Collectors.toList()));
        ArrayList<DeptListDTO.DepartmentBean> departmentBeans = sortDept(deptList.getDepartment(), deleteDeptId);
        for (DeptListDTO.DepartmentBean j : departmentBeans) {
          LogUtils.info(logger, file, "Delete Enterprise WeChat department，id:" + j.getId());
          DefaultResultDTO defaultResultDTO1 = this.wechatCorpAddressService.deleteDeptById(j.getId(), accessToken);
          if (WechatErrorCode.SUCCESS.equals(defaultResultDTO1.getErrcode())) {
            successDeptIdMap.put(j.getId(), null);
            resultCount.deptSuccess();
            continue;
          }
          LogUtils.error(logger, file, "Delete failed: " + defaultResultDTO1.getErrmsg());
          resultCount.deptFail();
        }
        continue;
      }
      LogUtils.info(logger, file, "Delete Enterprise WeChat department，id:" + deleteDeptId);
      DefaultResultDTO defaultResultDTO = this.wechatCorpAddressService.deleteDeptById(deleteDeptId, accessToken);
      if (WechatErrorCode.SUCCESS.equals(defaultResultDTO.getErrcode())) {
        successDeptIdMap.put(deleteDeptId, null);
        resultCount.deptSuccess();
        continue;
      }
      LogUtils.error(logger, file, "Delete failed: " + defaultResultDTO.getErrmsg());
      resultCount.deptFail();
    }
  }

  private void updateDeptList(File file, List<WechatSyncDeptDTO> updateDeptList, Map<Long, Long> successDeptIdMap, String accessToken, ResultCount resultCount) {
    for (WechatSyncDeptDTO j : updateDeptList) {
      boolean isParentIdMap = convertDeptParentId(j, successDeptIdMap);
      LogUtils.info(logger, file, "Update Enterprise WeChat department:" + j.toString());
      if (!isParentIdMap) {
        resultCount.deptFail();
        LogUtils.error(logger, file, "Update Enterprise WeChat department failed, parent department does not exist");
        continue;
      }
      DefaultResultDTO defaultResultDTO = this.wechatCorpAddressService.updateDept(j, accessToken);
      if (WechatErrorCode.SUCCESS.equals(defaultResultDTO.getErrcode())) {
        successDeptIdMap.put(j.getId(), null);
        resultCount.deptSuccess();
        continue;
      }
      LogUtils.error(logger, file, "Update failed: " + defaultResultDTO.getErrmsg());
      resultCount.deptFail();
    }
  }

  private void deleteUsers(File file, List<String> deleteUserIds, List<String> successUserIds, String accessToken, ResultCount resultCount) {
    if (!CollectionUtils.isEmpty(deleteUserIds)) {
      LogUtils.info(logger, file, "Delete Enterprise WeChat employees in batches:" + JSON.toJSONString(deleteUserIds));
      DefaultResultDTO defaultResultDTO = this.wechatCorpAddressService.batchDeleteUser(deleteUserIds, accessToken);
      if (WechatErrorCode.SUCCESS.equals(defaultResultDTO.getErrcode())) {
        LogUtils.error(logger, file, "Delete failed: " + defaultResultDTO.getErrmsg());
        resultCount.userFail(deleteUserIds.size());
      } else {
        successUserIds.addAll(deleteUserIds);
        resultCount.userSuccess(deleteUserIds.size());
      }
    }
  }

  private void insertUsers(File file, List<WechatSyncUserDTO> insertUsers, Map<Long, Long> successDeptIdMap, List<String> successUserIds, String accessToken, ResultCount resultCount) {
    if (!CollectionUtils.isEmpty(insertUsers))
      for (WechatSyncUserDTO j : insertUsers) {
        boolean isAllDepartIdsMap = convertUserDepart(j, successDeptIdMap);
        LogUtils.info(logger, file, "Create Enterprise WeChat employees: " + j.toString());
        if (!isAllDepartIdsMap) {
          LogUtils.error(logger, file, "Create employee failed, department does not exist.");
          resultCount.userFail(1);
          continue;
        }
        DefaultResultDTO user = this.wechatCorpAddressService.createUser(j, accessToken);
        if (WechatErrorCode.SUCCESS.equals(user.getErrcode())) {
          successUserIds.add(j.getUserid());
          resultCount.userSuccess(1);
          continue;
        }
        if (WechatErrorCode.MOBILE_EXISTS.equals(user.getErrcode()) || WechatErrorCode.USERID_EXISTS
                .equals(user.getErrcode())) {
          LogUtils.info(logger, file, "Employee already exists, update employee.");
          DefaultResultDTO defaultResultDTO = this.wechatCorpAddressService.updateUser(j, accessToken);
          if (WechatErrorCode.SUCCESS.equals(defaultResultDTO.getErrcode())) {
            successUserIds.add(j.getUserid());
            resultCount.userSuccess(1);
            continue;
          }
          resultCount.userFail(1);
          LogUtils.error(logger, file, "Update failed：" + defaultResultDTO.getErrmsg());
          continue;
        }
        resultCount.userFail(1);
        LogUtils.error(logger, file, "Create failed：" + user.getErrmsg());
      }
  }

  private void updateUsers(File file, Map<String, WechatSyncUserDTO> updateUsersMap, Map<Long, Long> successDeptIdMap, List<String> successUserIds, String accessToken, ResultCount resultCount) {
    if (!CollectionUtils.isEmpty(updateUsersMap.values()))
      for (WechatSyncUserDTO j : updateUsersMap.values()) {
        boolean isAllDepartIdsMap = convertUserDepart(j, successDeptIdMap);
        LogUtils.info(logger, file, "Update Enterprise WeChat employees: " + j);
        if (!isAllDepartIdsMap) {
          LogUtils.error(logger, file, "Update employee failed, department does not exist.");
          resultCount.userFail(1);
          continue;
        }
        DefaultResultDTO defaultResultDTO = this.wechatCorpAddressService.updateUser(j, accessToken);
        if (WechatErrorCode.SUCCESS.equals(defaultResultDTO.getErrcode())) {
          successUserIds.add(j.getUserid());
          resultCount.userSuccess(1);
          continue;
        }
        LogUtils.error(logger, file, "Update failed：" + defaultResultDTO.getErrmsg());
        resultCount.userFail(1);
      }
  }

  public static class ResultCount {
    private int deptSuccessCount = 0;

    private int deptFailCount = 0;

    private int userSuccessCount = 0;

    private int userFailCount = 0;

    void deptSuccess() {
      this.deptSuccessCount++;
    }

    void deptFail() {
      this.deptFailCount++;
    }

    void userSuccess(int count) {
      this.userSuccessCount += count;
    }

    void userFail(int count) {
      this.userFailCount += count;
    }

    int getDeptSuccessCount() {
      return this.deptSuccessCount;
    }

    int getDeptFailCount() {
      return this.deptFailCount;
    }

    int getUserSuccessCount() {
      return this.userSuccessCount;
    }

    int getUserFailCount() {
      return this.userFailCount;
    }
  }

  private ArrayList<WechatSyncDeptDTO> sortDept(List<WechatSyncDeptDTO> deptDTOList) {
    ArrayList<WechatSyncDeptDTO> sortDept = new ArrayList<>();
    List<Long> collect = (List<Long>)deptDTOList.stream().map(WechatSyncDeptDTO::getId).collect(Collectors.toList());
    boolean init = true;
    while (!CollectionUtils.isEmpty(deptDTOList)) {
      if (init) {
        List<Long> finalCollect = collect;
        List<WechatSyncDeptDTO> rootDept = deptDTOList.stream().filter(e -> (WechatConstans.ROOT_DEPT_ID.equals(e.getParentid()) || !finalCollect.contains(e.getParentUnitId()))).collect(Collectors.toList());
        collect = (List<Long>)rootDept.stream().map(WechatSyncDeptDTO::getId).collect(Collectors.toList());
        sortDept.addAll(rootDept);
        deptDTOList.removeAll(rootDept);
        init = false;
        continue;
      }
      List<Long> finalCollect = collect;
      List<WechatSyncDeptDTO> depts = (List<WechatSyncDeptDTO>)deptDTOList.stream().filter(e -> finalCollect.contains(e.getParentUnitId())).collect(Collectors.toList());
      collect = (List<Long>)depts.stream().map(WechatSyncDeptDTO::getId).collect(Collectors.toList());
      sortDept.addAll(depts);
      deptDTOList.removeAll(depts);
    }
    return sortDept;
  }

  private ArrayList<DeptListDTO.DepartmentBean> sortDept(List<DeptListDTO.DepartmentBean> departmentBeans, Long rootId) {
    List<Long> rootIds = null;
    Long finalRootId = rootId;
    boolean init = true;
    ArrayList<DeptListDTO.DepartmentBean> sortDept = new ArrayList<>();
    while (!CollectionUtils.isEmpty(departmentBeans)) {
      if (init) {
        List<DeptListDTO.DepartmentBean> rootDept = (List<DeptListDTO.DepartmentBean>)departmentBeans.stream().filter(j -> j.getId().equals(finalRootId)).collect(Collectors.toList());
        sortDept.addAll(rootDept);
        departmentBeans.removeAll(rootDept);
        rootDept = (List<DeptListDTO.DepartmentBean>)departmentBeans.stream().filter(j -> Objects.equals(j.getParentid(), finalRootId)).collect(Collectors.toList());
        sortDept.addAll(rootDept);
        departmentBeans.removeAll(rootDept);
        rootIds = (List<Long>)rootDept.stream().map(DeptListDTO.DepartmentBean::getId).collect(Collectors.toList());
        init = false;
        continue;
      }
      ArrayList<DeptListDTO.DepartmentBean> otherDept = new ArrayList<>();
      for (DeptListDTO.DepartmentBean departmentBean : departmentBeans) {
        if (rootIds.contains(departmentBean.getParentid()))
          otherDept.add(departmentBean);
      }
      sortDept.addAll(otherDept);
      departmentBeans.removeAll(otherDept);
      rootIds = (List<Long>)otherDept.stream().map(DeptListDTO.DepartmentBean::getId).collect(Collectors.toList());
    }
    Collections.reverse(sortDept);
    return sortDept;
  }

  protected SyncCorpResultDTO getSyncCorpResultDTO(SyncCorpResultDTO syncCorpResultDTO, File file) {
    try {
      syncCorpResultDTO.setLog(FileUtils.readFileToString(file, StandardCharsets.UTF_8));
    } catch (IOException e) {
      logger.error("Failed to read log from file ! message ", e);
    }
    FileUtils.deleteQuietly(file);
    return syncCorpResultDTO;
  }

  private boolean convertDeptParentId(WechatSyncDeptDTO syncDeptDTO, Map<Long, Long> successDeptIdMap) {
    if (!WechatConstans.ROOT_DEPT_ID.equals(syncDeptDTO.getParentid()) && syncDeptDTO.getParentid() == null) {
      if (successDeptIdMap.containsKey(syncDeptDTO.getParentUnitId())) {
        syncDeptDTO.setParentid(successDeptIdMap.get(syncDeptDTO.getParentUnitId()));
        return true;
      }
      return false;
    }
    return true;
  }

  private boolean convertUserDepart(WechatSyncUserDTO syncUserDTO, Map<Long, Long> successDeptIdMap) {
    List<Long> department = syncUserDTO.getDepartment();
    List<Boolean> isDepartIdsMap = syncUserDTO.getIsDepartIdsMap();
    boolean isAllDepartIdsMap = true;
    for (int i = 0; i < isDepartIdsMap.size(); i++) {
      if (isDepartIdsMap.get(i) != null && !((Boolean)isDepartIdsMap.get(i)).booleanValue()) {
        Long departId = successDeptIdMap.get(department.get(i));
        if (departId != null) {
          department.set(i, departId);
        } else {
          isAllDepartIdsMap = false;
        }
      }
    }
    return isAllDepartIdsMap;
  }

  private boolean checkDeptId(Long id) {
    return (id.longValue() <= WechatConstans.MAX_DEPT_ID.longValue());
  }
}
